package hy;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class Search {
    RestHighLevelClient cli;
    SearchRequest req;
    SearchSourceBuilder sb;


    @Before
    public void init() {
        cli=new RestHighLevelClient(
                RestClient.builder(new HttpHost("192.168.188.100",9200,"http"))
        );
        req = new SearchRequest().indices("user");
        sb=new SearchSourceBuilder();

    }
    @After
    public void end()throws Exception{
        req.source(sb);
        //开始查询
        SearchResponse resp = cli.search(req, RequestOptions.DEFAULT);
        //获取查询结果
        SearchHits hits = resp.getHits();
        System.out.println("一共查询到的数量："+hits.getTotalHits());
        hits.forEach(h->{
            System.out.println(h.getSourceAsString());
            //高亮显示时使用
            //Text[]arr=h.getHighlightFields().get("name").fragments();
            //System.out.println(arr[0].string());
        });
        cli.close();
    }

    @Test//1.查询所有
    public void searchAll(){
        sb.query(QueryBuilders.matchAllQuery());
    }
    @Test//2.根据条件查询
    public void searchByCondition(){
        sb.query(QueryBuilders.termQuery("name","a5"));
    }

    @Test//3.分页查询
    public void searchByPage(){
        int pageNo=1,pageSize=2;
        sb.from((pageNo-1)*pageSize).size(pageSize);
    }

    @Test//4.对结果排序查询
    public void searchByOrder(){
        sb.sort("age", SortOrder.DESC);
    }

    @Test//5.过滤显示的字段:参数1表示要显示什么字段，如果要显示的字段多，可用参数2表示不显示哪些字段
    public void searchByField() throws Exception{
        sb.fetchSource(new String[]{"name"},null);
    }
    @Test//6.多条件查询:must/mustNot逻辑与,should逻辑或
    public void searchByMultiCondition() throws Exception{
        BoolQueryBuilder bq= QueryBuilders.boolQuery();
        bq.must(QueryBuilders.matchQuery("name","a3")).mustNot(QueryBuilders.matchQuery("age",23));
//        bq.should(QueryBuilders.matchQuery("name","a3")).should(QueryBuilders.matchQuery("age",34));
        sb.query(bq);
    }

    @Test//7.范围查找:greater than equal
    public void searchByRange() throws Exception{
        RangeQueryBuilder rq=QueryBuilders.rangeQuery("age").gte(30).lte(35);
        sb.query(rq);
    }
    @Test//8.模糊查找
    public void searchByLike() throws Exception{
        //fuzziness:按给定的关键字a1查询，允许有一个字符的偏差，能查出a1,a2,a3...。
        sb.query(QueryBuilders.fuzzyQuery("name","a1").fuzziness(Fuzziness.ONE));
    }

    @Test//9.高亮查询
    public void searchWithHighLight() throws Exception{
        HighlightBuilder hb=new HighlightBuilder().preTags("<font color='red'>").postTags("</font>").field("name");
        //通配符查询
        QueryBuilder tb=QueryBuilders.wildcardQuery("name", "*");
        sb.highlighter(hb).query(tb);
    }
}
